﻿using System;
using System.Linq;
using System.Reflection;

namespace BusinessFramework
{
    [AttributeUsage(AttributeTargets.Property)]
    public abstract class PropertyValidationAttribute : Attribute
    {
        protected internal abstract Validation GetValidation(PropertyInfo propertyInfo);
        protected internal virtual void ValidatePropertyUsage(PropertyInfo propertyInfo)
        {
            foreach (var validPropertyType in GetValidPropertyTypes())
            {
                if (validPropertyType.IsAssignableFrom(propertyInfo.PropertyType))
                    return;
            }

            throw new InvalidOperationException(
                string.Format("{2} rule is not valid on {3} properties: {0}.{1}", propertyInfo.DeclaringType.Name,
                              propertyInfo.Name,
                              GetType().Name.EndsWith("Attribute")
                                  ? GetType().Name.Substring(0, GetType().Name.Length - 9)
                                  : GetType().Name, propertyInfo.PropertyType.Name));
        }

        public BrokenRuleSeverity? Severity { get; set; }
        public string Message { get; set; }

        protected internal virtual Type[] GetValidPropertyTypes()
        {
            return new Type[0];
        }
    }
}